home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume25 / setd < prev    next >
Encoding:
Text File  |  1992-01-11  |  48.6 KB  |  2,105 lines

  1. Newsgroups: comp.sources.unix
  2. From: sunil@hal.com (Sunil Savkar)
  3. Subject: v25i106: setd V1.7 -- Set Directory and Mark Utilities
  4. Sender: sources-moderator@pa.dec.com
  5. Approved: vixie@pa.dec.com
  6.  
  7. Submitted-By: sunil@hal.com (Sunil Savkar)
  8. Posting-Number: Volume 25, Issue 106
  9. Archive-Name: setd
  10.  
  11. setd -- (Set Directory and Mark Utilities version 1.7)
  12.  
  13. Only works in UNIX and tested on Suns, HPs, RS/6000, etcetera
  14.  
  15.     sunil@hal.com (Sunil Savkar)
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  22. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  23. # If this archive is complete, you will see the following message at the end:
  24. #        "End of shell archive."
  25. # Contents:  mark.c setd.c enum.h macros.h types.h mark.1 setd.1
  26. #   Makefile README DISCLOSURE
  27. # Wrapped by sunil@jaguar on Wed Jan  8 22:14:42 1992
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f 'mark.c' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'mark.c'\"
  31. else
  32. echo shar: Extracting \"'mark.c'\" \(14830 characters\)
  33. sed "s/^X//" >'mark.c' <<'END_OF_FILE'
  34. X/*
  35. X *  MARK
  36. X *  Mark Directory
  37. X *  Version 1.7
  38. X *
  39. X *  Sunil William Savkar
  40. X *  sunil@hal.com
  41. X *  Copyright (c) 1991
  42. X *  All Rights Reserved
  43. X *
  44. X *  DISCLOSURE
  45. X *
  46. X *  This source may be modified or copied freely.  The intent
  47. X *  is the free distribution of a useful utility used for moving
  48. X *  between directories.  Any modifications and additions, along
  49. X *  with bug reports should be sent to the author, so all might
  50. X *  benefit!
  51. X *
  52. X *  DESCRIPTION
  53. X * 
  54. X *  Mark directory utility used in conjunction with the
  55. X *  setd command to allow ease of directory changes.
  56. X *
  57. X *  MODIFICATION HISTORY
  58. X *
  59. X *  8/2/91  Sunil William Savkar
  60. X *          Changed code to allow running on HPs.
  61. X *
  62. X *  12/6/92 Sunil William Savkar
  63. X *          Changed code to allow for alphabetical sorting
  64. X *          of the mark file (easier to peruse).
  65. X *
  66. X *  Please send all updates along with suggestions
  67. X *  to sunil@hal.com
  68. X */
  69. X
  70. X#if (MACH == hp || MACH == m88k || MACH == rs)
  71. X#include <stdlib.h>
  72. X#else
  73. X#include <alloca.h>
  74. X#endif
  75. X#include <stdio.h>
  76. X#include <string.h>
  77. X#include <ctype.h>
  78. X#include "macros.h"
  79. X#include "enum.h"
  80. X#include "types.h"
  81. X
  82. X
  83. X/*
  84. X *  command[]
  85. X *
  86. X *  This array holds all the strings which are command line arguments
  87. X *  recognized, along with the enumerated type they match with.
  88. X */
  89. X
  90. XCOMMAND_NODE command[] = {  K_MARK_DIR, "", K_REMOVE_MARK, "-rm", 
  91. X                            K_HELP, "-h", K_HELP, "-help", K_VERSION,
  92. X                            "-v", K_VERSION, "-ver", K_VERSION, "version",
  93. X                            K_RESET_MARKS, "-reset", K_REMOVE_MARK, "-remove",
  94. X                            K_LIST_MARKS, "-list", K_REFRESH_MARKS, "-r",
  95. X                            K_LIST_MARKS, "-l", 
  96. X                            K_REFRESH_MARKS, "-refresh", K_REFRESH_MARKS, "-ref",
  97. X                            K_NULL, NULL};
  98. X
  99. X/*
  100. X *  version_header[]
  101. X */
  102. X
  103. Xstatic char version_header[] =
  104. X"Mark Directory\tv1.7\tSunil William Savkar\n";
  105. X
  106. X/*
  107. X *  help_header[]
  108. X */
  109. X
  110. Xstatic  char    help_header[] =
  111. X"Mark Directory\tv1.7\nusage:\tmark <options>\n\n\
  112. Xoption\t\t\tdescription\n\n\
  113. X<cr>\n\
  114. X-l<ist>\t\t\tLists current marks and their directories\n\
  115. X[mark]\t\t\tAliases current directory to alphanumeric mark name\n\
  116. X-rm [mark]\n\
  117. X-remove [mark]\t\tRemoves specified mark\n\
  118. X-v<ersion>\t\tPrints current version of the program\n\
  119. X-h<elp>\t\t\tThis help message\n\
  120. X-reset\t\t\tClears all marks in the current environment\n\
  121. X-r<efresh>\t\tRefreshes all marks in the current environment\n\
  122. X\nexamples:\tmark xxx, mark -list, mark -reset, mark -rm xxx\n";
  123. X
  124. X/*
  125. X *  boolean read_into_list( char *mark_fil, 
  126. X *                          LIST_NODE **list_head)
  127. X *
  128. X *  This routine opens the passed mark file, holding all the currently
  129. X *  enabled marks, and parses them into the linked list of marks
  130. X *  with their expansions.
  131. X */
  132. X
  133. Xboolean read_into_list(mark_fil,  /*  The mark file                         */
  134. X                       list_head, /*  Pointer to the head of the mark list  */ 
  135. X                       list_tail)
  136. Xchar *mark_fil;
  137. XLIST_NODE **list_head;
  138. XLIST_NODE **list_tail;
  139. X{
  140. X
  141. X  FILE *mark_fp;                  /*  Pointer to the mark file stream       */
  142. X  LIST_NODE *new_ptr;             /*  New list element to add to marks      */
  143. X  char setenv[MAX_LINE];          /*  Contains the setenv line in mark file */
  144. X  char mark[MAX_LINE];            /*  The mark string which will expand     */
  145. X  char path[MAX_LINE];            /*  The expansion of the mark             */
  146. X  char buffer[MAX_LINE];          /*  Temporary buffer to hold information  */
  147. X
  148. X  /*
  149. X   *  Open the mark file.
  150. X   */
  151. X
  152. X  *list_tail = *list_head;
  153. X  if (!(mark_fp = fopen(mark_fil, "r"))) {
  154. X
  155. X    fprintf(stderr, "read_into_list:  Unable to open %s\n", mark_fil);
  156. X    return FALSE;
  157. X  }
  158. X
  159. X  /*
  160. X   *  Now continue reading the file and setting up the linked list.
  161. X   */
  162. X
  163. X  while (fgets(buffer, MAX_LINE, mark_fp)) {
  164. X
  165. X    /*
  166. X     *  Format for the file is : "setenv mark_<mark_name> <mark_expansion>"
  167. X     */
  168. X
  169. X    sscanf(buffer, "%s mark_%s %s", setenv, mark, path);
  170. X
  171. X    if (STREQU(setenv, "unsetenv")) continue;
  172. X    if (!STREQU(setenv, "setenv")) {
  173. X
  174. X      fprintf(stderr, "read_into_list:  Error in mark database\n");
  175. X      return FALSE;
  176. X    }
  177. X
  178. X    /*
  179. X     *  Set up a new node.
  180. X     */
  181. X
  182. X    if (!(new_ptr = (LIST_NODE *)malloc(sizeof(LIST_NODE)))) {
  183. X
  184. X      fprintf( stderr, "read_into_list: error mallocing new structure\n");
  185. X      return FALSE;
  186. X    }
  187. X
  188. X    new_ptr->unset_flag = FALSE;
  189. X    if (!(new_ptr->mark = (char *)malloc(strlen(mark) + 1))) {
  190. X
  191. X      fprintf( stderr, "read_into_list: error mallocing new mark string\n");
  192. X      return FALSE;
  193. X    } else if (!(new_ptr->path = (char *)malloc(strlen(path) + 1))) {
  194. X
  195. X      fprintf( stderr, "read_into_list: error mallocing new expand string\n");
  196. X      return FALSE;
  197. X    }
  198. X    new_ptr->next = NULL;
  199. X    strcpy(new_ptr->mark, mark); strcpy(new_ptr->path, path);
  200. X
  201. X    /*
  202. X     *  Insert the new mark into the list.
  203. X     */
  204. X
  205. X    if (*list_head == NULL) {
  206. X
  207. X      *list_head = *list_tail = new_ptr;
  208. X    } else {
  209. X
  210. X      (*list_tail)->next = new_ptr;
  211. X      *list_tail = new_ptr;
  212. X    }
  213. X  }
  214. X
  215. X  /*
  216. X   *  Done with generating the linked list of current marks.
  217. X   */
  218. X
  219. X  fclose(mark_fp);
  220. X  return TRUE;
  221. X}
  222. X
  223. X/*
  224. X *  boolean initialize( char **pwd,
  225. X *                      char *mark_fil,
  226. X *                      LIST_NODE **list_head,
  227. X *                      LIST_NODE **list_tail)
  228. X *
  229. X *  This routine is called to initialize the variables and list
  230. X *  of marks currently set.
  231. X */
  232. X
  233. Xboolean initialize( pwd, 
  234. X                    mark_fil, 
  235. X                    list_head,
  236. X                    list_tail)
  237. XLIST_NODE **list_tail;
  238. XLIST_NODE **list_head;
  239. Xchar *mark_fil;
  240. Xchar **pwd;
  241. X{
  242. X
  243. X  FILE *mark_fp;
  244. X  char *getenv();
  245. X  char *ptr;
  246. X
  247. X  /*
  248. X   *  Get current directory and pointer to the mark directory.
  249. X   */
  250. X
  251. X#ifdef HP
  252. X
  253. X  if (!(getcwd((*pwd = (char *)malloc(MAX_LINE)), MAX_LINE))) {
  254. X#else
  255. X
  256. X  if (!(*pwd = getenv("PWD"))) {
  257. X#endif
  258. X
  259. X    fprintf(stderr, "initialize:  Unable to get environment var $PWD\n");
  260. X    return FALSE;
  261. X  }
  262. X
  263. X  /*
  264. X   *  Notice we would like to strip off the /tmp_mount from the *pwd,
  265. X   *  if it exists!
  266. X   */
  267. X
  268. X  if (strncmp(*pwd, "/tmp_mnt", 8) == 0) {
  269. X    *pwd += 8;
  270. X  }
  271. X
  272. X  if (!(ptr = getenv("MARK_DIR"))) {
  273. X
  274. X    fprintf(stderr, "initialize:  Must set environment var $MARK_DIR\n");
  275. X    return FALSE;
  276. X  } else {
  277. X
  278. X    /*
  279. X     *  Construct mark data base file pointer.
  280. X     */
  281. X
  282. X    sprintf( mark_fil, "%s/mark_db", ptr);
  283. X  }
  284. X
  285. X  if (!(mark_fp = fopen(mark_fil, "a"))) {
  286. X
  287. X    fprintf(stderr, "initialize:  Unable to open %s\n", mark_fil);
  288. X    return FALSE;
  289. X  }
  290. X
  291. X  fclose(mark_fp);
  292. X
  293. X  /*
  294. X   *  Read marks into a linked list, with the mark string,
  295. X   *  and the path string.
  296. X   */
  297. X
  298. X  if (!read_into_list(mark_fil, list_head, list_tail)) {
  299. X
  300. X    fprintf(stderr, "initialize:  Unable to read mark file %s\n", mark_fil);
  301. X    return FALSE;
  302. X  }
  303. X
  304. X  return TRUE;
  305. X}  
  306. X
  307. X/*
  308. X *  T_COMM parse( char *option)
  309. X *
  310. X *  This routine returns the enumeration for the given string which
  311. X *  represents an option on the command line.  Options can be anything
  312. X *  from -help for help, to the mark to be set.
  313. X */
  314. X
  315. XT_COMM parse( option)  /*  The string representing the option requested     */
  316. Xchar *option;
  317. X{
  318. X
  319. X  int j;
  320. X  char *ptr;
  321. X
  322. X  /*
  323. X   *  No dash indicates no real option, but just a directory to mark.
  324. X   */
  325. X
  326. X  if (*option != '-') {
  327. X
  328. X    return K_MARK_DIR;
  329. X  }
  330. X
  331. X  /*
  332. X   *  Must be one of the commands, else there is
  333. X   *  an error.
  334. X   */
  335. X
  336. X  for (j = 0; ptr = command[j].text; j++) {
  337. X
  338. X    if (STREQU(ptr, option)) break;
  339. X  }
  340. X
  341. X  if (!ptr) {
  342. X
  343. X    fprintf(stderr, "parse: unrecognized option from main (%s)\n", option);
  344. X    return K_NULL;
  345. X  }
  346. X
  347. X  return command[j].type;
  348. X}
  349. X
  350. Xboolean list_marks( list_ptr)
  351. XLIST_NODE *list_ptr;
  352. X{
  353. X
  354. X  
  355. X  /*
  356. X   *  Each line consists of the mark, and then the pathname.
  357. X   */
  358. X
  359. X  fprintf(stdout, "MARK\t\tPATH\n----\t\t----\n");
  360. X  for (; list_ptr; list_ptr = list_ptr->next) {
  361. X
  362. X    fprintf(stdout, "%s\t\t%s\n", list_ptr->mark, list_ptr->path);
  363. X  }
  364. X
  365. X  return TRUE;
  366. X}
  367. X
  368. X/*
  369. X *  boolean mark_dir( char *pwd,
  370. X *                    char *mark,
  371. X *                    LIST_NODE **list_head,
  372. X *                    LIST_NODE **list_tail)
  373. X *
  374. X *  This routine adds a new mark with expansion to the given list.
  375. X */
  376. X
  377. Xboolean mark_dir(pwd, 
  378. X                 mark, 
  379. X                 list_head,
  380. X                 list_tail)
  381. XLIST_NODE **list_head,
  382. X          **list_tail;
  383. Xchar *pwd;
  384. Xchar *mark;
  385. X{
  386. X
  387. X  char *ptr;
  388. X  LIST_NODE *new_ptr, *list_ptr;
  389. X
  390. X  /*
  391. X   *  A mark must be alphanumeric.
  392. X   */
  393. X
  394. X  for (ptr = mark; *ptr != '\0'; ptr++) {
  395. X
  396. X    if (!(isalnum(*ptr) || (*ptr == '_'))) {
  397. X
  398. X      fprintf(stderr, "mark_dir: mark must be alphanumeric\n");
  399. X      return FALSE;
  400. X    }
  401. X  }
  402. X
  403. X  /*
  404. X   *  If there is an old mark by the same name, just change the
  405. X   *  path for that mark.
  406. X   */
  407. X
  408. X  for (list_ptr = *list_head; list_ptr; list_ptr = list_ptr->next) {
  409. X
  410. X    if (STREQU(mark, list_ptr->mark)) break;
  411. X  }
  412. X
  413. X  if (list_ptr) {
  414. X
  415. X    free(list_ptr->path);
  416. X    list_ptr->path = pwd;
  417. X  } else if (!(new_ptr = (LIST_NODE *)malloc(sizeof(LIST_NODE)))) {
  418. X
  419. X    fprintf(stderr, "mark_dir: error allocating space in list\n");
  420. X    return FALSE;
  421. X  } else {
  422. X
  423. X    new_ptr->unset_flag = FALSE;
  424. X    new_ptr->next = NULL;
  425. X    new_ptr->mark = mark;
  426. X    new_ptr->path = pwd;
  427. X
  428. X    if (*list_head == NULL) {
  429. X
  430. X      *list_head = *list_tail = new_ptr;
  431. X    } else {
  432. X
  433. X      (*list_tail)->next = new_ptr;
  434. X      *list_tail = new_ptr;
  435. X    }
  436. X  }
  437. X
  438. X  fprintf(stderr, "mark_dir: mark \"%s\" (%s) set\n", mark, pwd);
  439. X  return TRUE;
  440. X}
  441. X
  442. X/*
  443. X *  boolean remove_mark( char *mark,
  444. X *                       LIST_NODE *list_ptr)
  445. X *
  446. X *  This routine is used to remove a mark from the given list (through
  447. X *  including an unsetenv declarator in the mark file.
  448. X */
  449. X
  450. Xboolean remove_mark(mark, 
  451. X                    list_ptr)
  452. Xchar *mark;
  453. XLIST_NODE *list_ptr;
  454. X{
  455. X
  456. X  for (; list_ptr; list_ptr = list_ptr->next) {
  457. X
  458. X    if (STREQU(list_ptr->mark, mark)) {
  459. X
  460. X      list_ptr->unset_flag = TRUE;
  461. X      fprintf( stderr, "mark_dir: mark \"%s\" (%s) removed\n", mark, 
  462. X               list_ptr->path);
  463. X      return TRUE;
  464. X    }
  465. X  }
  466. X
  467. X  fprintf(stderr, "mark_dir: mark \"%s\" not found\n", mark);
  468. X  return FALSE;
  469. X}
  470. X
  471. X/*
  472. X *  boolean reset_marks( LIST_NODE *list_ptr)
  473. X *
  474. X *  This routine resets the marks by unsetenv all of them.
  475. X */
  476. X
  477. Xboolean reset_marks( list_ptr)
  478. XLIST_NODE *list_ptr;
  479. X{
  480. X
  481. X  /*
  482. X   *  Go through all the marks and set their unset_flag.
  483. X   */
  484. X
  485. X  for (; list_ptr; list_ptr = list_ptr->next) list_ptr->unset_flag = TRUE;
  486. X
  487. X  return TRUE;
  488. X}
  489. X
  490. X/*
  491. X *  boolean sort_list( list_head)
  492. X *
  493. X *  This routine simply pops off the old list and rearranges into a sorted
  494. X *  order.  This simple routine is written instead of using the system
  495. X *  sort command.
  496. X */
  497. X
  498. Xvoid sort_list( list_head)
  499. XLIST_NODE **list_head;
  500. X{
  501. X
  502. X  LIST_NODE *sort_head, 
  503. X            *sort_tail,
  504. X            *list_ptr, 
  505. X            *old_ptr, 
  506. X            *sort_ptr;
  507. X
  508. X  sort_head = old_ptr = NULL;
  509. X
  510. X  /*
  511. X   *  Pop off the old list and rearrange in the new sort list.
  512. X   */
  513. X
  514. X  while (*list_head) {
  515. X
  516. X    list_ptr = *list_head;
  517. X    *list_head = (*list_head)->next;
  518. X    list_ptr->next = NULL;
  519. X
  520. X    /*
  521. X     *  No sorted list exists.
  522. X     */
  523. X
  524. X    if (!sort_head) {
  525. X
  526. X      sort_head = sort_tail = list_ptr;
  527. X      continue;
  528. X    } else {
  529. X
  530. X      /*
  531. X       *  Check for mark precedence over current list head.
  532. X       */
  533. X      if (strcmp( list_ptr->mark, sort_head->mark) < 0) {
  534. X
  535. X        list_ptr->next = sort_head;
  536. X        sort_head = list_ptr;
  537. X
  538. X      /* 
  539. X       *  Check for mark being of lesser precedence than the tail.
  540. X       */
  541. X
  542. X      } else if (strcmp( list_ptr->mark, sort_tail->mark) > 0) {
  543. X
  544. X        sort_tail->next = list_ptr;
  545. X        sort_tail = list_ptr;
  546. X      } else {
  547. X
  548. X        /*
  549. X         *  Insert the mark somewhere within the list alphabetically.
  550. X         */
  551. X
  552. X        for (sort_ptr = sort_head; sort_ptr; old_ptr = sort_ptr, sort_ptr = sort_ptr->next) {
  553. X
  554. X          if (strcmp( list_ptr->mark, sort_ptr->mark) < 0) {
  555. X
  556. X            old_ptr->next = list_ptr;
  557. X            list_ptr->next = sort_ptr;
  558. X            break;
  559. X      }
  560. X    }
  561. X      }
  562. X    }
  563. X  }
  564. X
  565. X  /*
  566. X   *  Set the new list head.
  567. X   */
  568. X
  569. X  *list_head = sort_head;
  570. X}
  571. X
  572. Xboolean update_file( mark_fil, list_ptr)
  573. Xchar *mark_fil;
  574. XLIST_NODE *list_ptr;
  575. X{
  576. X
  577. X  FILE *mark_fp;
  578. X
  579. X  /*
  580. X   *  Write the new list of marks to the update file.
  581. X   */
  582. X
  583. X  if (!(mark_fp = fopen(mark_fil, "w"))) {
  584. X
  585. X    fprintf(stderr, "update_file: Unable to update %s\n", mark_fil);
  586. X    return FALSE;
  587. X  }
  588. X
  589. X  for (; list_ptr; list_ptr = list_ptr->next) {
  590. X
  591. X    if (!list_ptr->unset_flag) {
  592. X
  593. X      fprintf(mark_fp, "setenv mark_%s %s\n", list_ptr->mark, list_ptr->path);
  594. X    } else {
  595. X
  596. X      fprintf(mark_fp, "unsetenv mark_%s\n", list_ptr->mark);
  597. X    }
  598. X  }
  599. X
  600. X  fclose(mark_fp);
  601. X  return TRUE;
  602. X}
  603. X
  604. X/*
  605. X *  main( int argc,
  606. X *        char *argv[])
  607. X *
  608. X *  The main event.
  609. X */
  610. X
  611. Xmain(argc, 
  612. X     argv)
  613. Xchar *argv[];
  614. Xint argc;
  615. X{
  616. X
  617. X  LIST_NODE *list_head,
  618. X            *list_tail;
  619. X  int i;
  620. X  char mark_fil[MAX_LINE];
  621. X  char *pwd;
  622. X  T_COMM option;
  623. X  
  624. X  list_head = list_tail = NULL;
  625. X
  626. X  /*
  627. X   *  First we must initialize, getting pointer to the
  628. X   *  mark file, and read in the current directory.
  629. X   */
  630. X
  631. X  if (!initialize(&pwd, mark_fil, &list_head, &list_tail)) {
  632. X
  633. X    fprintf(stderr, "mark: error code from initialize\n");
  634. X    exit(-1);
  635. X  }
  636. X
  637. X  /*
  638. X   *  Now we have the file pointer for mark, and the current
  639. X   *  directory.  It is time to start parsing the arguments
  640. X   *  on the command line.
  641. X   */
  642. X
  643. X  for (i = 1; i <= argc; i++) {
  644. X
  645. X    if (argc == 1) {
  646. X
  647. X      option = K_LIST_MARKS;
  648. X    } else if (i == argc) {
  649. X
  650. X       break;
  651. X    } else if ((option = parse( argv[i])) == K_NULL) {
  652. X
  653. X
  654. X      fprintf(stderr, "mark: error code from parse\n");
  655. X      exit(-1);
  656. X    }
  657. X
  658. X    /*
  659. X     *  Switch, based upon the given option, to the
  660. X     *  proper function.
  661. X     */
  662. X
  663. X    switch (option) {
  664. X
  665. X    case K_MARK_DIR:
  666. X
  667. X      if (!mark_dir(pwd, argv[i], &list_head, &list_tail)) {
  668. X
  669. X        fprintf(stderr, "mark: error code from mark_dir\n");
  670. X        exit(-1);
  671. X      }
  672. X      break;
  673. X
  674. X    case K_REMOVE_MARK: 
  675. X      if (!remove_mark(argv[++i], list_head)) {
  676. X
  677. X        fprintf(stderr, "mark: error code from remove_mark\n");
  678. X        exit(-1); 
  679. X      }
  680. X      break;
  681. X
  682. X    case K_LIST_MARKS: 
  683. X      if (!list_marks(list_head)) {
  684. X
  685. X        fprintf(stderr, "mark:  error code from list_marks\n");
  686. X        exit(-1);
  687. X      }
  688. X      break;
  689. X
  690. X    case K_VERSION:
  691. X      fprintf(stdout, version_header);
  692. X      break;
  693. X
  694. X    case K_HELP:
  695. X      fprintf(stdout, help_header);
  696. X      break;
  697. X
  698. X    case K_RESET_MARKS: 
  699. X      if (!reset_marks(list_head)) {
  700. X
  701. X        fprintf(stderr, "mark: error code from reset_marks\n");
  702. X        exit(-1);
  703. X      }
  704. X      break;
  705. X
  706. X    case K_REFRESH_MARKS: break;
  707. X    default: break;
  708. X    }
  709. X  }
  710. X
  711. X  if (option == K_MARK_DIR) sort_list( &list_head);
  712. X  if (!update_file(mark_fil, list_head)) {
  713. X
  714. X    fprintf(stderr, "mark: error code from update_file\n");
  715. X    exit(-1);
  716. X  }
  717. X
  718. X  exit(0);
  719. X}
  720. END_OF_FILE
  721. if test 14830 -ne `wc -c <'mark.c'`; then
  722.     echo shar: \"'mark.c'\" unpacked with wrong size!
  723. fi
  724. # end of 'mark.c'
  725. fi
  726. if test -f 'setd.c' -a "${1}" != "-c" ; then 
  727.   echo shar: Will not clobber existing file \"'setd.c'\"
  728. else
  729. echo shar: Extracting \"'setd.c'\" \(15273 characters\)
  730. sed "s/^X//" >'setd.c' <<'END_OF_FILE'
  731. X/*
  732. X *  SETD
  733. X *  Set Directory
  734. X *  Version 1.7
  735. X *
  736. X *  Sunil William Savkar
  737. X *  sunil@hal.com
  738. X *  Copyright (c) 1991
  739. X *  All Rights Reserved
  740. X *
  741. X *  DISCLOSURE
  742. X *
  743. X *  This source may be modified or copied freely.  The intent
  744. X *  is the free distribution of a useful utility used for moving
  745. X *  between directories.  Any modifications and additions, along
  746. X *  with bug reports should be sent to the author, so all might
  747. X *  benefit!
  748. X *
  749. X *  DESCRIPTION
  750. X * 
  751. X *  Set directory utility used in conjunction with the
  752. X *  mark command to allow ease of directory changes.
  753. X *
  754. X *  MODIFICATION HISTORY
  755. X *
  756. X *  8/2/91 Hunter Scales
  757. X *         Changed code to allow running on HPs.
  758. X *  8/20/91 Sunil William Savkar
  759. X *         Allow fall through of illegal directory
  760. X *         change so cd can try to use cdpath variable.
  761. X *  12/6/92 Sunil William Savkar
  762. X *         Added changes to allow a mark as a base of a
  763. X *         full pathname, thus not needing multiple
  764. X *         marks for subdirectories under a common point.
  765. X *
  766. X *  Please send all updates along with suggestions
  767. X *  to sunil@hal.com
  768. X */
  769. X
  770. X#if (MACH == hp || MACH == m88k || MACH == rs)
  771. X#include <stdlib.h>
  772. X#else
  773. X#include <alloca.h>
  774. X#endif
  775. X#include <stdio.h>
  776. X#include <string.h>
  777. X#include <ctype.h>
  778. X#include "macros.h"
  779. X#include "enum.h"
  780. X#include "types.h"
  781. X
  782. X/*
  783. X * Global Variable Definitions
  784. X */
  785. X
  786. XCOMMAND_NODE command[] = {
  787. X
  788. X  K_SETD_DIR, "",
  789. X  K_SETD_HOME, "",
  790. X  K_POS_QUEUE, "",
  791. X  K_BACK_QUEUE, "",
  792. X  K_LIST_QUEUE, "-list", 
  793. X  K_LIST_QUEUE, "-l",
  794. X  K_MAX_QUEUE, "-max", 
  795. X  K_MAX_QUEUE, "-m", 
  796. X  K_HELP, "-h", 
  797. X  K_HELP, "-help", 
  798. X  K_VERSION, "-v", 
  799. X  K_VERSION, "-ver", 
  800. X  K_VERSION, "-version", 
  801. X  K_NULL, NULL
  802. X};
  803. X
  804. Xstatic char version_header[] = "Set Directory\tv1.7\tSunil William Savkar\n";
  805. X
  806. Xstatic  char    help_header[] =
  807. X"Set Directory\tv1.7\nusage:\tcd <options>\n\n\
  808. Xoption\t\tdescription\n\n\
  809. X[path]\t\tAttempts change to specified directory pathname\n\
  810. X[mark]\t\tAttempts change to directory specified by the mark alias\n\
  811. X[mark]/[path]\tAttempts change to base mark plus appended pathname\n\
  812. X[env]\t\tAttempts change to directory spec'd by environment variable\n\
  813. X%%[path]\t\tAttempts change to subdirectory pathname of root one above\n\
  814. X-l<ist>\t\tLists previous directories up to maximum set list length\n\
  815. X-m<ax>\t\tSets the maximum depth of the past directory list\n\
  816. Xnumeric\t\tChanges directory to specified list pos, or offset from top (-)\n\
  817. X\nexamples:\tcd ~savkar, cd %bin, cd -4, cd MARK_NAME, cd MARK_NAME/xxx\n";
  818. X
  819. X/*
  820. X *  boolean conv_to_dec( char *string,
  821. X *                       int  *conv_dec)
  822. X *
  823. X *  conv_to_dec translates the string to a decimal
  824. X *  value, and returns this decimal value in conv_dec.
  825. X *  If an error occurs during conversion, the function
  826. X *  returns false, else it returns true.
  827. X */
  828. X
  829. Xboolean conv_to_dec(string, 
  830. X                    conv_dec)
  831. Xchar *string;  /*  The string to convert                       */
  832. Xint *conv_dec; /*  The variable to store the converted integer */
  833. X{
  834. X
  835. X  int num = 0,  /*  Used to analyze and store shifted value    */
  836. X      muln = 1; /*  +/- multiplier factor                      */
  837. X
  838. X  /*
  839. X   *  Check for the sign of the passed string
  840. X   */
  841. X
  842. X  if (*string == '-') {
  843. X
  844. X    if (*(++string) == '\0') return FALSE;
  845. X    muln = -1;
  846. X  } else if (*string == '+') {
  847. X
  848. X    if (*(++string) == '\0') return FALSE;
  849. X  }
  850. X
  851. X  /*
  852. X   *  Increment through the string and put together the base ten
  853. X   *  number which is represented.
  854. X   */
  855. X
  856. X  for (; *string != '\0'; string++) {
  857. X
  858. X    if (!isdigit(*string)) return FALSE;
  859. X    num = num*10 + (*string - '0');
  860. X  }
  861. X
  862. X  *conv_dec = num*muln;
  863. X  return TRUE;
  864. X}
  865. X
  866. X/*
  867. X *  void push_list( LIST_NODE **list,
  868. X *                  LIST_NODE *element,
  869. X *                  int *length)
  870. X *
  871. X *  Push new node onto the list.
  872. X */
  873. X
  874. Xvoid push_list(list, element, length)
  875. XLIST_NODE *element;
  876. XLIST_NODE **list;
  877. Xint *length;
  878. X{
  879. X
  880. X  element->next = *list;
  881. X  *list = element;
  882. X  (*length)++;
  883. X}
  884. X
  885. X/*
  886. X *  LIST_NODE *shift_list( LIST_NODE *list,
  887. X *                         int *length)
  888. X *
  889. X *  Shift off the last element of the list, and pass
  890. X *  it to the caller.
  891. X */
  892. X
  893. XLIST_NODE *shift_list(list, 
  894. X                      length)
  895. XLIST_NODE **list;
  896. Xint *length;
  897. X{
  898. X
  899. X  LIST_NODE *prev, *end;
  900. X
  901. X  if (!(*list)) return NULL;
  902. X
  903. X  if (!(*list)->next) {
  904. X
  905. X    end = *list;
  906. X    *list = NULL;
  907. X  } else {
  908. X
  909. X    for (end = *list; end->next; end = end->next) ;
  910. X    for (prev = *list; prev->next != end; prev = prev->next) ;
  911. X      prev->next = NULL;
  912. X  }
  913. X
  914. X  (*length)--;
  915. X  return (end);
  916. X}
  917. X
  918. X/*
  919. X *  boolean read_into_list( char *setd_fil,
  920. X *                          LIST_NODE **list_head,
  921. X *                          int *max_queue,
  922. X *                          int *list_length)
  923. X *
  924. X *  read_into_list attempts to open the setd database and read
  925. X *  the list of prior directory changes into the queue.  An error
  926. X *  is returned if unable to open or read the setd db file. 
  927. X *
  928. X *  The database of prior locations is read into a list pointed at
  929. X *  by *list_head. The length of the list is in the list_length
  930. X *  variable, and the max_queue variable is also set at this point.
  931. X */
  932. X
  933. Xboolean read_into_list(setd_fil, list_head, max_queue, list_length)
  934. Xchar *setd_fil;
  935. XLIST_NODE **list_head;
  936. Xint *max_queue;
  937. Xint *list_length;
  938. X{
  939. X
  940. X  FILE *setd_fp;
  941. X  LIST_NODE *new_ptr;
  942. X  char path[MAX_LINE];
  943. X
  944. X  *list_length = 0;
  945. X
  946. X  if (!(setd_fp = fopen(setd_fil, "r"))) {
  947. X
  948. X    fprintf(stderr, "read_into_list:  Unable to open %s\n", setd_fil);
  949. X    return FALSE;
  950. X  }
  951. X
  952. X  /*
  953. X   *  First argument is the maximum queue length.
  954. X   */
  955. X
  956. X  *max_queue = 0;
  957. X  fscanf(setd_fp, "%d", max_queue);
  958. X  if (!(*max_queue)) {
  959. X
  960. X    *max_queue = 10;
  961. X  }
  962. X    
  963. X  /*
  964. X   *  Now continue reading the file and setting up the linked list.
  965. X   */
  966. X
  967. X  while (fscanf(setd_fp, "%s", path) == 1) {
  968. X
  969. X    /*
  970. X     *  Set up a new node.
  971. X     */
  972. X
  973. X    new_ptr = (LIST_NODE *)malloc(sizeof(LIST_NODE));
  974. X    new_ptr->path = (char *)malloc(strlen(path) + 1);
  975. X    new_ptr->next = NULL;
  976. X    strcpy(new_ptr->path, path);
  977. X
  978. X    push_list( list_head, new_ptr, list_length);
  979. X  }
  980. X
  981. X  fclose(setd_fp);
  982. X  return TRUE;
  983. X}
  984. X
  985. Xboolean initialize( home, pwd, setd_fil, list_head, max_queue, list_length)
  986. XLIST_NODE **list_head;
  987. Xchar *setd_fil;
  988. Xchar **pwd;
  989. Xchar **home;
  990. Xint *max_queue, *list_length;
  991. X{
  992. X
  993. X  FILE *setd_fp;
  994. X  char *getenv();
  995. X  char *ptr;
  996. X
  997. X  /*
  998. X   *  Get current directory and pointer to the mark directory.
  999. X   */
  1000. X
  1001. X#ifdef HP
  1002. X
  1003. X  if (!(getcwd((*pwd = (char *)malloc(MAX_LINE), MAX_LINE))) {
  1004. X#else
  1005. X
  1006. X  if (!(*pwd = getenv("PWD"))) {
  1007. X#endif  
  1008. X
  1009. X    fprintf(stderr, "initialize:  Unable to get environment var $PWD\n");
  1010. X    return FALSE;
  1011. X  }
  1012. X
  1013. X#ifdef HP
  1014. X
  1015. X  /*
  1016. X   *  Notice we would like to strip off the /tmp_mount from the *pwd,
  1017. X   *  if it exists!
  1018. X   */
  1019. X
  1020. X  if (strncmp(*pwd, "/tmp_mnt", 8) == 0) {
  1021. X    *pwd += 8;
  1022. X  }
  1023. X#endif
  1024. X
  1025. X  if (!(*home = getenv("HOME"))) {
  1026. X
  1027. X    fprintf(stderr, "initialize:  Unable to get environment var $HOME\n");
  1028. X    return FALSE;
  1029. X  }
  1030. X  
  1031. X  if (!(ptr = getenv("SETD_DIR"))) {
  1032. X
  1033. X    fprintf(stderr, "initialize:  Must set environment var $SETD_DIR\n");
  1034. X    return FALSE;
  1035. X  } else {
  1036. X
  1037. X    /*
  1038. X     *  Construct setd data base file pointer.
  1039. X     */
  1040. X
  1041. X    sprintf( setd_fil, "%s/setd_db", ptr);
  1042. X  }
  1043. X
  1044. X  if (!(setd_fp = fopen(setd_fil, "a"))) {
  1045. X
  1046. X    fprintf(stderr, "initialize:  Unable to open %s\n", setd_fil);
  1047. X    return FALSE;
  1048. X  }
  1049. X
  1050. X  fclose(setd_fp);
  1051. X
  1052. X  /*
  1053. X   *  Read queue into a linked list, with the path string.
  1054. X   */
  1055. X
  1056. X  if (!read_into_list(setd_fil, list_head, max_queue, list_length)) {
  1057. X
  1058. X    fprintf(stderr, "initialize:  Unable to read setd file %s\n", setd_fil);
  1059. X    return FALSE;
  1060. X  }
  1061. X
  1062. X  return TRUE;
  1063. X}  
  1064. X
  1065. XT_COMM parse( option)
  1066. Xchar *option;
  1067. X{
  1068. X
  1069. X  int j;
  1070. X  int num;
  1071. X  char *ptr;
  1072. X
  1073. X  if (*option != '-') {
  1074. X
  1075. X    return K_SETD_DIR;
  1076. X  }
  1077. X
  1078. X  /*
  1079. X   *  Must be one of the commands, else there is
  1080. X   *  an error.
  1081. X   */
  1082. X
  1083. X  for (j = 0; (ptr = command[j].text) && !STREQU( ptr, option); j++) ;
  1084. X
  1085. X  if (!ptr) {
  1086. X
  1087. X    if (conv_to_dec(option, &num)) return K_SETD_DIR;
  1088. X    fprintf(stderr, "parse: unrecognized option from main (%s)\n", option);
  1089. X    return K_NULL;
  1090. X  }
  1091. X
  1092. X  return command[j].type;
  1093. X}
  1094. X
  1095. Xboolean list_queue( list_ptr, max_queue)
  1096. XLIST_NODE *list_ptr;
  1097. Xint max_queue;
  1098. X{
  1099. X
  1100. X  int i;
  1101. X  
  1102. X  /*
  1103. X   *  Each line consists of the mark, and then the pathname.
  1104. X   */
  1105. X
  1106. X  fprintf(stderr, "Current Queue (Max = %d)\n-------------\n\n", max_queue);
  1107. X  for (i = 0; list_ptr; list_ptr = list_ptr->next, i++) {
  1108. X
  1109. X    fprintf(stderr, "%d. %s\n", i, list_ptr->path);
  1110. X  }
  1111. X
  1112. X  return TRUE;
  1113. X}
  1114. X
  1115. Xboolean update_file( setd_fil, list_head, max_queue)
  1116. Xchar *setd_fil;
  1117. XLIST_NODE *list_head;
  1118. Xint max_queue;
  1119. X{
  1120. X
  1121. X  LIST_NODE *element, *last;
  1122. X  FILE *setd_fp;
  1123. X
  1124. X  /*
  1125. X   *  Write the new list of marks to the update file.
  1126. X   */
  1127. X
  1128. X  if (!(setd_fp = fopen(setd_fil, "w"))) {
  1129. X
  1130. X    fprintf(stderr, "update_file: Unable to update %s\n", setd_fil);
  1131. X    return FALSE;
  1132. X  }
  1133. X
  1134. X  fprintf(setd_fp, "%d\n", max_queue);
  1135. X
  1136. X  /*
  1137. X   *  Use a non-recursive inverted write to the file to speed things up,
  1138. X   *  ever so slightly.  There is a need for speed in this filter.
  1139. X   *  The user shouldn't be aware of all the translations.
  1140. X   */
  1141. X
  1142. X  if (list_head) {
  1143. X
  1144. X    last = NULL;
  1145. X
  1146. X    /*
  1147. X     *  Go to the last element, which hasn't been written yet.
  1148. X     */
  1149. X
  1150. X    do {
  1151. X
  1152. X      for (element = list_head; element->next != last; element = element->next) ;
  1153. X      fprintf(setd_fp, "%s\n", element->path);
  1154. X      last = element;
  1155. X    } while (element != list_head);
  1156. X  }
  1157. X
  1158. X  fclose(setd_fp);
  1159. X  return TRUE;
  1160. X}
  1161. X
  1162. X/*
  1163. X *  boolean return_dest( char *dest,
  1164. X *                       char *path,
  1165. X *                       LIST_NODE *list,
  1166. X *                       int list_length)
  1167. X *
  1168. X *  return_dest attempts to translate the given path
  1169. X *  into a proper destination, whether an environment
  1170. X *  variable, mark, setd list position, or same level
  1171. X *  subdirectory.
  1172. X */
  1173. X
  1174. Xboolean return_dest( dest, 
  1175. X                     path, 
  1176. X                     list, 
  1177. X                     list_length)
  1178. Xchar *path;
  1179. Xchar *dest;
  1180. XLIST_NODE *list;
  1181. Xint list_length;
  1182. X{
  1183. X
  1184. X  char temp[MAX_LINE];
  1185. X  char front[MAX_LINE];
  1186. X  char *getenv();
  1187. X  char *mark;
  1188. X  char *env;
  1189. X  char *ptr;
  1190. X  int num = 0;
  1191. X  sprintf( temp, "mark_%s", path);
  1192. X
  1193. X  /*
  1194. X   *  Two types of mark uses are able to be recognized by
  1195. X   *  setd.  The first is just setting directory to the
  1196. X   *  mark by itself.  Then the translation is simple.
  1197. X   *  The second method is by using the mark as a base,
  1198. X   *  and adding an extended path after the mark.  This
  1199. X   *  method requires a reconstruction of a string to
  1200. X   *  attempt proper mark resolution with the subdir string
  1201. X   *  specified.
  1202. X   */
  1203. X
  1204. X  mark = getenv(temp);
  1205. X  env  = getenv(path);
  1206. X
  1207. X  strcpy( temp, path);
  1208. X  if (ptr = strchr( temp, '/')) {
  1209. X
  1210. X    /*
  1211. X     *  Zero out everything past the slash, and
  1212. X     *  attempt to translate the temporary "mark"
  1213. X     *  or environment variable.
  1214. X     */
  1215. X
  1216. X    *ptr = '\0';
  1217. X    ptr = strchr( path, '/');
  1218. X    sprintf( front, "mark_%s", temp);
  1219. X    if (mark = getenv( front)) {
  1220. X
  1221. X      sprintf( temp, "%s%s", mark, ptr);
  1222. X      mark = temp;
  1223. X    } else if (env = getenv( front)) {
  1224. X
  1225. X      sprintf( temp, "%s%s", env, ptr);
  1226. X      env = temp;
  1227. X    }
  1228. X  }
  1229. X
  1230. X  if (chdir(path) == 0) {
  1231. X
  1232. X    strcpy(dest, path);
  1233. X  } else if (mark) {
  1234. X
  1235. X    strcpy(dest, mark);
  1236. X  } else if (env) {
  1237. X
  1238. X    strcpy(dest, env);
  1239. X  } else if (conv_to_dec(path, &num)) {
  1240. X
  1241. X    if ((num = abs(num)) > (list_length - 1)) {
  1242. X
  1243. X      fprintf(stderr, "return_dest: out of bounds (-%d <= num <= %d)\n", 
  1244. X              list_length, list_length);
  1245. X      return FALSE;
  1246. X    }
  1247. X
  1248. X    for (; num; num--) list = list->next;
  1249. X    strcpy(dest, list->path);
  1250. X
  1251. X  } else if (*path == '%') {
  1252. X
  1253. X    sprintf( temp, "../%s", (path + 1));
  1254. X    return (return_dest(dest, temp, list, list_length));
  1255. X
  1256. X  } else {
  1257. X
  1258. X    /*
  1259. X     *  Let normal cd handle error message.
  1260. X     */
  1261. X
  1262. X    strcpy(dest, path);    
  1263. X  }
  1264. X
  1265. X  return TRUE;
  1266. X}
  1267. X
  1268. X/*
  1269. X * boolean add_pwd( LIST_NODE *list_head,
  1270. X *                  char *pwd,
  1271. X *                  int max_queue,
  1272. X *                  int *list_length,
  1273. X *                  char *setd_fil)
  1274. X *
  1275. X *  add_pwd attempts to push the given pwd onto the queue, unless
  1276. X *  the pwd is the same as the current pwd at the top of the stack.
  1277. X */
  1278. X
  1279. Xboolean add_pwd( list_head, 
  1280. X                 pwd, 
  1281. X                 max_queue, 
  1282. X                 list_length, 
  1283. X                 setd_fil)
  1284. XLIST_NODE **list_head;
  1285. Xint *list_length;
  1286. Xint max_queue;
  1287. Xchar *pwd;
  1288. Xchar *setd_fil;
  1289. X{
  1290. X
  1291. X  LIST_NODE *pwd_ptr;
  1292. X
  1293. X  if (*list_head && STREQU((*list_head)->path, pwd)) return TRUE;
  1294. X
  1295. X  pwd_ptr = (LIST_NODE *)malloc(sizeof(LIST_NODE));
  1296. X  pwd_ptr->next = NULL;
  1297. X  pwd_ptr->path = (char *)malloc(strlen(pwd) + 1);
  1298. X  strcpy(pwd_ptr->path, pwd);
  1299. X  
  1300. X  push_list(list_head, pwd_ptr, list_length);
  1301. X
  1302. X  if (*list_length > max_queue) free(shift_list(list_head, list_length));
  1303. X
  1304. X  if (!update_file( setd_fil, *list_head, max_queue)) {
  1305. X
  1306. X    fprintf(stderr, "add_pwd: error in update_file\n");
  1307. X    return FALSE;
  1308. X  }
  1309. X
  1310. X  return TRUE;
  1311. X}
  1312. X
  1313. X/*
  1314. X *  main( int argc, 
  1315. X *        char *argv[])
  1316. X */
  1317. X
  1318. Xmain(argc, argv)
  1319. Xchar *argv[];
  1320. Xint argc;
  1321. X{
  1322. X
  1323. X  LIST_NODE *list_head;
  1324. X  int old_max;
  1325. X  int max_queue;
  1326. X  int i;
  1327. X  char setd_fil[MAX_LINE];
  1328. X  char *pwd;
  1329. X  char *home;
  1330. X  char dest[MAX_LINE];
  1331. X  T_COMM option;
  1332. X  int list_length;  
  1333. X
  1334. X  list_head = NULL;
  1335. X
  1336. X  /*
  1337. X   *  First we must initialize, getting pointer to the
  1338. X   *  mark file, and read in the current directory.
  1339. X   */
  1340. X
  1341. X  if (!initialize(&home, &pwd, setd_fil, &list_head, &max_queue, &list_length)) {
  1342. X
  1343. X    fprintf(stderr, "setd: error code from initialize\n");
  1344. X    exit(0);
  1345. X  }
  1346. X
  1347. X  /*
  1348. X   *  Push the current position onto the stack, if not already
  1349. X   *  done.  That is, if the current pwd is the same as the top
  1350. X   *  of the stack, then do not add again.
  1351. X   */
  1352. X
  1353. X  if (!add_pwd( &list_head, pwd, max_queue, &list_length, setd_fil)) {
  1354. X
  1355. X    fprintf( stderr, "setd: error from add_pwd\n");
  1356. X    exit(-1);
  1357. X  }
  1358. X
  1359. X  strcpy(dest, pwd);
  1360. X
  1361. X  /*
  1362. X   *  Now we have the file pointer for mark, and the current
  1363. X   *  directory.  It is time to start parsing the arguments
  1364. X   *  on the command line.
  1365. X   */
  1366. X
  1367. X  for (i = 1; i <= argc; i++) {
  1368. X
  1369. X    if (argc == 1) {
  1370. X
  1371. X      option = K_SETD_HOME;
  1372. X    } else if (i == argc) {
  1373. X
  1374. X       break;
  1375. X    } else if ((option = parse( argv[i])) == K_NULL) {
  1376. X
  1377. X
  1378. X      fprintf(stderr, "setd: error code from parse\n");
  1379. X    }
  1380. X
  1381. X    /*
  1382. X     *  Switch, based upon the given option, to the
  1383. X     *  proper function.
  1384. X     */
  1385. X
  1386. X    switch (option) {
  1387. X
  1388. X    case K_VERSION:
  1389. X      fprintf(stderr, version_header);
  1390. X      break;
  1391. X
  1392. X    case K_HELP:
  1393. X      fprintf(stderr, help_header);
  1394. X      break;
  1395. X
  1396. X    case K_SETD_HOME:
  1397. X      strcpy(dest, home);
  1398. X      break;
  1399. X
  1400. X    case K_SETD_DIR:
  1401. X      if (!return_dest(dest, argv[i], list_head, list_length)) {
  1402. X
  1403. X        fprintf(stderr, "setd: error code from return_dest\n");
  1404. X      }
  1405. X      break;
  1406. X
  1407. X    case K_LIST_QUEUE:
  1408. X      if (!list_queue(list_head, max_queue)) {
  1409. X
  1410. X        fprintf(stderr, "setd: error code from list_queue\n");
  1411. X      }
  1412. X      break;
  1413. X
  1414. X    case K_MAX_QUEUE:
  1415. X
  1416. X      old_max = max_queue;
  1417. X      if ((++i >= argc) || (!conv_to_dec(argv[i], &max_queue))
  1418. X          || (max_queue <= 0)) {
  1419. X
  1420. X        fprintf(stderr, "setd: invalid maximum specified\n");
  1421. X      } else {
  1422. X
  1423. X        if (old_max != max_queue) list_head = NULL;
  1424. X
  1425. X        if (!update_file( setd_fil, list_head, max_queue)) {
  1426. X
  1427. X          fprintf(stderr, "setd: error in update_file\n");
  1428. X          exit(-1);
  1429. X        }
  1430. X      }
  1431. X      break;
  1432. X
  1433. X    default: break;
  1434. X    }
  1435. X  }
  1436. X
  1437. X  fprintf(stdout, dest);
  1438. X
  1439. X  exit(0);
  1440. X}
  1441. X
  1442. END_OF_FILE
  1443. if test 15273 -ne `wc -c <'setd.c'`; then
  1444.     echo shar: \"'setd.c'\" unpacked with wrong size!
  1445. fi
  1446. # end of 'setd.c'
  1447. fi
  1448. if test -f 'enum.h' -a "${1}" != "-c" ; then 
  1449.   echo shar: Will not clobber existing file \"'enum.h'\"
  1450. else
  1451. echo shar: Extracting \"'enum.h'\" \(1289 characters\)
  1452. sed "s/^X//" >'enum.h' <<'END_OF_FILE'
  1453. X/*
  1454. X *  enum.h
  1455. X *
  1456. X *  Enumerated Types File for both Mark and Set Directory
  1457. X *
  1458. X *  Sunil William Savkar
  1459. X *  sunil@hal.com
  1460. X *  Copyright (c) 1991
  1461. X *  All Rights Reserved
  1462. X *
  1463. X *  DISCLOSURE
  1464. X *
  1465. X *  This source may be modified or copied freely.  The intent
  1466. X *  is the free distribution of a useful utility used for moving
  1467. X *  between directories.  Any modifications and additions, along
  1468. X *  with bug reports should be sent to the author, so all might
  1469. X *  benefit!
  1470. X *
  1471. X *  DESCRIPTION
  1472. X * 
  1473. X *  This module contains the enumerated type definitions for
  1474. X *  the command line arguments.  Inclusive are a set of enumerations
  1475. X *  for such commands as the version, removal, inclusion, etcetera
  1476. X *  of marks and of set directory commands.  The same file is included
  1477. X *  by both setd and mark.
  1478. X */
  1479. X
  1480. X/*
  1481. X *  typedef enum T_COMM
  1482. X *
  1483. X *  The enumerated command arguments for mark.
  1484. X */
  1485. X
  1486. X#ifdef MARK
  1487. Xtypedef enum T_COMM {
  1488. X
  1489. X  K_VERSION,
  1490. X  K_HELP,
  1491. X  K_MARK_DIR,
  1492. X  K_REMOVE_MARK,
  1493. X  K_REFRESH_MARKS,
  1494. X  K_LIST_MARKS,
  1495. X  K_RESET_MARKS,
  1496. X  K_NULL
  1497. X} T_COMM;
  1498. X#endif
  1499. X
  1500. X/*
  1501. X *  typedef enum T_COMM
  1502. X *
  1503. X *  The enumerated command arguments for setd.
  1504. X */
  1505. X
  1506. X#ifdef SETD
  1507. Xtypedef enum T_COMM {
  1508. X
  1509. X  K_SETD_DIR,
  1510. X  K_MAX_QUEUE,
  1511. X  K_SETD_HOME,
  1512. X  K_LIST_QUEUE,
  1513. X  K_POS_QUEUE,
  1514. X  K_BACK_QUEUE,
  1515. X  K_VERSION,
  1516. X  K_HELP,
  1517. X  K_NULL
  1518. X} T_COMM;
  1519. X#endif
  1520. X
  1521. END_OF_FILE
  1522. if test 1289 -ne `wc -c <'enum.h'`; then
  1523.     echo shar: \"'enum.h'\" unpacked with wrong size!
  1524. fi
  1525. # end of 'enum.h'
  1526. fi
  1527. if test -f 'macros.h' -a "${1}" != "-c" ; then 
  1528.   echo shar: Will not clobber existing file \"'macros.h'\"
  1529. else
  1530. echo shar: Extracting \"'macros.h'\" \(711 characters\)
  1531. sed "s/^X//" >'macros.h' <<'END_OF_FILE'
  1532. X/*
  1533. X *  macros.h
  1534. X *
  1535. X *  Macros File for both Mark and Set Directory
  1536. X *
  1537. X *  Sunil William Savkar
  1538. X *  sunil@hal.com
  1539. X *  Copyright (c) 1991
  1540. X *  All Rights Reserved
  1541. X *
  1542. X *  DISCLOSURE
  1543. X *
  1544. X *  This source may be modified or copied freely.  The intent
  1545. X *  is the free distribution of a useful utility used for moving
  1546. X *  between directories.  Any modifications and additions, along
  1547. X *  with bug reports should be sent to the author, so all might
  1548. X *  benefit!
  1549. X *
  1550. X *  DESCRIPTION
  1551. X * 
  1552. X *  This module contains all typed structures used by both
  1553. X *  setd and mark for changing directories or adding and/or
  1554. X *  deleting marks.
  1555. X */
  1556. X
  1557. X#define MAX_LINE 255
  1558. X#define FALSE 0
  1559. X#define TRUE 1
  1560. X#define STREQU(a, b) (strcmp( a, b) == 0)
  1561. END_OF_FILE
  1562. if test 711 -ne `wc -c <'macros.h'`; then
  1563.     echo shar: \"'macros.h'\" unpacked with wrong size!
  1564. fi
  1565. # end of 'macros.h'
  1566. fi
  1567. if test -f 'types.h' -a "${1}" != "-c" ; then 
  1568.   echo shar: Will not clobber existing file \"'types.h'\"
  1569. else
  1570. echo shar: Extracting \"'types.h'\" \(1279 characters\)
  1571. sed "s/^X//" >'types.h' <<'END_OF_FILE'
  1572. X/*
  1573. X *  types.h
  1574. X *
  1575. X *  Types File for both Mark and Set Directory
  1576. X *
  1577. X *  Sunil William Savkar
  1578. X *  sunil@hal.com
  1579. X *  Copyright (c) 1991
  1580. X *  All Rights Reserved
  1581. X *
  1582. X *  DISCLOSURE
  1583. X *
  1584. X *  This source may be modified or copied freely.  The intent
  1585. X *  is the free distribution of a useful utility used for moving
  1586. X *  between directories.  Any modifications and additions, along
  1587. X *  with bug reports should be sent to the author, so all might
  1588. X *  benefit!
  1589. X *
  1590. X *  DESCRIPTION
  1591. X * 
  1592. X *  This module contains all typed structures used by both
  1593. X *  setd and mark for changing directories or adding and/or
  1594. X *  deleting marks.
  1595. X */
  1596. X
  1597. X/*
  1598. X *  typedef int boolean
  1599. X *
  1600. X *  Type booleans to just be integers (TRUE or FALSE).
  1601. X */
  1602. X
  1603. Xtypedef int boolean;
  1604. X
  1605. X/*
  1606. X *  typedef struct COMMAND_NODE
  1607. X *
  1608. X *  Structure used to store a string command and its enumerated
  1609. X *  equivalent.  The enumerated equivalents can be found in enum.h
  1610. X */
  1611. X
  1612. Xtypedef struct COMMAND_NODE {
  1613. X
  1614. X  T_COMM type;
  1615. X  char   *text;
  1616. X} COMMAND_NODE;
  1617. X
  1618. X/*
  1619. X *  typedef struct LIST_NODE
  1620. X *
  1621. X *  This structure stores the list of marks, with the original
  1622. X *  mark, the path expansion for the mark, and a pointer to the
  1623. X *  next mark.
  1624. X */
  1625. X
  1626. Xtypedef struct LIST_NODE {
  1627. X
  1628. X  int unset_flag;
  1629. X  char *mark;
  1630. X  char *path;
  1631. X  struct LIST_NODE *next;
  1632. X} LIST_NODE;
  1633. X
  1634. X
  1635. X
  1636. X
  1637. END_OF_FILE
  1638. if test 1279 -ne `wc -c <'types.h'`; then
  1639.     echo shar: \"'types.h'\" unpacked with wrong size!
  1640. fi
  1641. # end of 'types.h'
  1642. fi
  1643. if test -f 'mark.1' -a "${1}" != "-c" ; then 
  1644.   echo shar: Will not clobber existing file \"'mark.1'\"
  1645. else
  1646. echo shar: Extracting \"'mark.1'\" \(2549 characters\)
  1647. sed "s/^X//" >'mark.1' <<'END_OF_FILE'
  1648. X.\" @(#)mark.1 1.7 92/01/07 SMI;
  1649. X.\" Updated 92/01/07
  1650. X.TH MARK 1 "07 January 1992"
  1651. X.SH NAME
  1652. X.TP 8
  1653. Xmark -
  1654. XProgram to keep track of database of directory marks, with each mark representing an aliased directory.
  1655. X.SH SYNOPSIS
  1656. X.TP 7
  1657. X.B mark
  1658. X[
  1659. X.B options
  1660. X]
  1661. X[
  1662. X.B directory mark
  1663. X]
  1664. X.SH DESCRIPTION
  1665. X.LP
  1666. X.B mark
  1667. Xis a utility which is used in conjunction
  1668. Xwith set directory,
  1669. X.BR setd(1)
  1670. X, to allow the user quick access to directory pathnames through marks.
  1671. X.LP
  1672. XThis program, combined with setd allows the user to freely
  1673. Xmark directories using a string for quick access.
  1674. X.SH INSTALLATION
  1675. X.LP
  1676. X.B mark
  1677. Xinstallation is quick and painless.  Both an environment
  1678. Xvariable and a mark alias must be set to store the mark database
  1679. Xand set-up mark to refresh the directory marks within the
  1680. Xenvironment.  Copying the three lines below for mark is all that
  1681. Xis needed.
  1682. X.LP
  1683. X       setenv MARK_DIR ~/bin
  1684. X       alias mark 'mark \!*; source $MARK_DIR/mark_db'
  1685. X       mark -refresh
  1686. X.LP
  1687. XIn the specific example, $MARK_DIR points to the user's bin
  1688. Xarea, thus allowing the user to always have a database of
  1689. Xmarks in a designated area for any number of processes.
  1690. X.LP
  1691. XThe alias of mark simply uses mark to set up the new line in
  1692. Xthe mark database file, with the source command updating the
  1693. Xenvironment variables used by setd.
  1694. X.SH OPTIONS
  1695. X.LP
  1696. X.TP 12
  1697. X.B <cr>
  1698. X.TP
  1699. X.B -l<ist>
  1700. XList directory marks.
  1701. X.br
  1702. XListing of all the marks set and their directory translation.
  1703. X.TP
  1704. X.B -rm
  1705. X[
  1706. X.B mark
  1707. X]
  1708. X.TP
  1709. X.B -remove
  1710. X[
  1711. X.B mark
  1712. X]
  1713. X.br
  1714. XRemove mark.
  1715. X.br
  1716. XRemoves the specified mark from  the mark database.
  1717. X.TP
  1718. X.B -v<ersion>
  1719. XVersion number.
  1720. X.br
  1721. XOutputs the version of mark being run.
  1722. X.TP
  1723. X.B -h<elp>
  1724. XShort help message.
  1725. X.br
  1726. XA condensed help  message  of the options.
  1727. X.TP
  1728. X.B -reset
  1729. XReset marks.
  1730. X.br
  1731. XTruncates the mark database.
  1732. X.TP
  1733. X.B -r<efresh>
  1734. XRefresh marks.
  1735. X.br
  1736. XRefreshes the shell with the marks in the database.
  1737. X.SH USAGE
  1738. X.LP
  1739. X.B mark
  1740. Xcan be simply used by changing directory and  then
  1741. Xsetting a mark name by the following
  1742. X.LP
  1743. X     mark [directory mark]
  1744. X.LP
  1745. Xwhich can then be used to  change  directory  using
  1746. X.B setd(1)
  1747. Xfrom  then  on!   To list marks, type mark and press return.
  1748. XUpon logging in, a  line  is  included  in  your  .cshrc  to
  1749. Xinvisibly  update  the  shell  with  the marks from the mark
  1750. Xdatabase.  If marks ever become corrupt,  a  simple  refresh
  1751. Xshould set things straight.
  1752. X.SH FILES
  1753. X$MARK_DIR/mark_db
  1754. X.SH SEE ALSO
  1755. X.B setd(1), cd(1)
  1756. X.SH AUTHOR
  1757. XSunil William Savkar
  1758. X.br
  1759. Xsunil@hal.com
  1760. X.br
  1761. XHaL Computer Systems Corporation
  1762. X.br
  1763. XDecember 26, 1991
  1764. X.SH VERSION
  1765. XCurrently version 1.7, 1/7/92
  1766. X
  1767. END_OF_FILE
  1768. if test 2549 -ne `wc -c <'mark.1'`; then
  1769.     echo shar: \"'mark.1'\" unpacked with wrong size!
  1770. fi
  1771. # end of 'mark.1'
  1772. fi
  1773. if test -f 'setd.1' -a "${1}" != "-c" ; then 
  1774.   echo shar: Will not clobber existing file \"'setd.1'\"
  1775. else
  1776. echo shar: Extracting \"'setd.1'\" \(4312 characters\)
  1777. sed "s/^X//" >'setd.1' <<'END_OF_FILE'
  1778. X.\" @(#)setd.1 1.7 92/01/07 SMI;
  1779. X.\" Updated 92/01/07
  1780. X.TH SETD 1 "07 January 1992"
  1781. X.SH NAME
  1782. X.TP 8
  1783. Xsetd -
  1784. XFilter program to change directory using marks, environment variables, or a built in queue.
  1785. X.SH SYNOPSIS
  1786. X.TP 7
  1787. X.B setd 
  1788. X[
  1789. X.B options
  1790. X] 
  1791. X[ 
  1792. X.B directory
  1793. X|
  1794. X.B mark
  1795. X[
  1796. X.B /directory
  1797. X] |
  1798. X.B env
  1799. X|
  1800. X.B offset
  1801. X|
  1802. X.B %directory
  1803. X]
  1804. X.TP
  1805. X.B cd
  1806. X[
  1807. X.B options
  1808. X] 
  1809. X[ 
  1810. X.B directory
  1811. X|
  1812. X.B mark
  1813. X[
  1814. X.B /directory
  1815. X] |
  1816. X.B env
  1817. X|
  1818. X.B offset
  1819. X|
  1820. X.B %directory
  1821. X]
  1822. X.SH DESCRIPTION
  1823. X.LP
  1824. X.B setd, set directory, is a filter utility interfaced
  1825. Xwith change directory,
  1826. X.BR cd(1)
  1827. X, to allow the user quick access
  1828. Xto directory pathnames through marks, environment variables,
  1829. Xoffsets in a queue, etcetera.
  1830. X.LP
  1831. XCombined with the mark filter utility, 
  1832. X.BR mark(1)
  1833. X, setd provides
  1834. Xa very powerful method to access frequently used directories
  1835. Xthrough mark aliases.  setd can also translate through a mark
  1836. Xwith a continuation of the directory description.  Thus the
  1837. Xuser can set a mark in a base directory and attach to sub-
  1838. Xdirectories under the base simply by specifying the mark + '/' + 
  1839. Xsub-directory structure.
  1840. X.LP
  1841. Xsetd also includes a queue which tracks a history of directory
  1842. Xpoints for the current process.  The depth of this queue is
  1843. Xconfigurable by the user, and a simple offset is used to access
  1844. Xa location in the queue.
  1845. X.LP
  1846. XThe use of environment variables is also supported, along with
  1847. Xtraversal along the same level of a directory tree.
  1848. X.SH INSTALLATION
  1849. X.LP
  1850. X.B setd
  1851. Xinstallation is quick and painless.  Both an environment
  1852. Xvariable and a cd alias must be set to store the queue database
  1853. Xand set-up setd to filter into the change directory command
  1854. Xrespectively.  Copying the two lines below for setd is all that
  1855. Xis needed.
  1856. X.LP
  1857. X       setenv SETD_DIR /usr/tmp
  1858. X       alias cd 'cd `setd \!*`'
  1859. X.LP
  1860. XIn the specific example, $SETD_DIR points to the /usr/tmp area,
  1861. Xthough most users will wish to actually set the pointer to their
  1862. Xbin area instead (for example, ~/bin).
  1863. X.LP
  1864. XThe alias of cd simply filters all input through the setd program
  1865. Xand directs the output to the cd command.  To see setd in action,
  1866. Xattempt to use setd separately, and notice the simple filtered 
  1867. Xoutput produced.  When installed with the alias, all commands
  1868. Xare seamless and accessible directly through cd.
  1869. X.SH OPTIONS
  1870. X.LP 
  1871. X.TP 10
  1872. X.B -l<ist>
  1873. XList queue.
  1874. X.br
  1875. XHistory of past directory accesses, up to the maximum
  1876. Xqueue depth specified by -max (or defaulting to 10).
  1877. X.TP
  1878. X.B -m<ax>
  1879. XMax queue depth.
  1880. X.br
  1881. XSets maximum depth for the history queue (defaults to
  1882. Xa maximum depth of 10 unless otherwise specified).
  1883. X.TP
  1884. X.B -v<ersion>
  1885. XVersion number.
  1886. X.br
  1887. XDisplays the version of setd being run.
  1888. X.TP
  1889. X.B -h<elp>
  1890. XHelp message.
  1891. X.br
  1892. XEnumerates all the options.
  1893. X.SH USAGE
  1894. X.LP
  1895. XWhen interfaced with cd, cd will perform exactly as before
  1896. Xexcepting for special character sequences which are filtered
  1897. Xby setd.  Below are several examples of cd with the setd 
  1898. Xfilter.
  1899. X.LP
  1900. X.TP 4
  1901. X.B (1)  cd [ directory ]
  1902. XA straight directory string is given, thus cd automatically
  1903. Xchanges to the given directory.
  1904. X.TP
  1905. X.B (2)  cd [ mark ]
  1906. XA mark alias was given, thus setd performs translation from
  1907. Xthe mark to the corresponding directory.
  1908. X.TP
  1909. X.B (3)  cd [ env ]
  1910. XAn environment variable was specified, which is also translated
  1911. Xfrom the variable into the corresponding directory.
  1912. X.TP
  1913. X.B (4)  cd [ mark/directory ]
  1914. Xsetd expands the given mark with the attached directory fully
  1915. Xinto the translated mark with the directory appended to the
  1916. Xtranslated path.
  1917. X.TP
  1918. X.B (5)  cd [ offset ]
  1919. XGiven a queue with a maximum depth of X, the offset number can
  1920. Xtake on values from zero through the maximum value minus one.
  1921. XThe offset values are symmetric around zero, thus the following
  1922. Xtwo lines are equivalent:
  1923. X.br
  1924. X            cd -1
  1925. X        cd +1
  1926. X.br
  1927. XBoth of these commands read the directory in position one off
  1928. Xthe queue and set the user to the location.  Notice position
  1929. Xone corresponds to the last directory accessed.
  1930. X.TP
  1931. X.B (6)  cd [ %directory ]
  1932. XFinally, the percent (%) option can be placed in front of  a
  1933. Xdirectory  name  to allow the user to specify a directory at
  1934. Xthe same level of hierarchy with the one currently set to.
  1935. X.SH FILES
  1936. X$SETD_DIR/setd_db
  1937. X.SH SEE ALSO
  1938. X.B mark(1), cd(1)
  1939. X.SH AUTHOR
  1940. XSunil William Savkar
  1941. X.br
  1942. Xsunil@hal.com
  1943. X.br
  1944. XHaL Computer Systems Corporation
  1945. X.br
  1946. XDecember 26, 1991
  1947. X.SH VERSION
  1948. XCurrently version 1.7, 1/7/92
  1949. END_OF_FILE
  1950. if test 4312 -ne `wc -c <'setd.1'`; then
  1951.     echo shar: \"'setd.1'\" unpacked with wrong size!
  1952. fi
  1953. # end of 'setd.1'
  1954. fi
  1955. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  1956.   echo shar: Will not clobber existing file \"'Makefile'\"
  1957. else
  1958. echo shar: Extracting \"'Makefile'\" \(1440 characters\)
  1959. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  1960. X#
  1961. X#  Makefile for setd and mark utilities
  1962. X#  Sunil William Savkar
  1963. X#  HaL Computer Sytems Corporation
  1964. X#  January 7, 1992
  1965. X#
  1966. X#  *  Must change the BINDIR, MANDIR to point to the
  1967. X#     appropriate areas
  1968. X#  *  Must change MACHINE_TYPE to reflect the type of machine
  1969. X#     you are running on (i.e.  HP, SUN, RS6000, etcetera)
  1970. X#
  1971. X
  1972. XBINDIR= /usr/bin
  1973. XMANDIR = /usr/man/man1
  1974. X
  1975. XTARGET1 = setd
  1976. XTARGET2 = mark
  1977. X
  1978. XCC    = cc
  1979. XMACHINE_TYPE = SUN
  1980. XOFLAGS    = -O 
  1981. XCFLAGS    = -D$(MACHINE_TYPE) $(OFLAGS) 
  1982. XLDFLAGS =
  1983. XMAN1 = setd.1
  1984. XMAN2 = mark.1
  1985. XSOURCES1 = setd.c
  1986. XSOURCES2 = mark.c
  1987. XOBJECTS1 = setd.o
  1988. XOBJECTS2 = mark.o
  1989. XINCLUDES =
  1990. X
  1991. Xall: $(TARGET1) $(TARGET2)
  1992. X
  1993. X$(TARGET1): $(OBJECTS1)
  1994. X    $(CC) $(LDFLAGS) $(OBJECTS1) -o $(TARGET1)
  1995. X$(TARGET2): $(OBJECTS2)
  1996. X    $(CC) $(LDFLAGS) $(OBJECTS2) -o $(TARGET2)
  1997. Xsetd.o: types.h enum.h macros.h setd.c
  1998. X    $(CC) $(CFLAGS) -DSETD -c $(INCLUDES) setd.c
  1999. Xmark.o: types.h enum.h macros.h mark.c
  2000. X    $(CC) $(CFLAGS) -DMARK -c $(INCLUDES) mark.c
  2001. Xclean    :
  2002. X        rm -f *.o
  2003. X
  2004. Xclobber :    clean
  2005. X        rm -f $(TARGET1)
  2006. X        rm -f $(TARGET2)
  2007. X
  2008. Xinstall :    all installman installexec
  2009. X
  2010. Xinstallman:
  2011. X    cp $(MAN1) $(MANDIR)/$(MAN1)
  2012. X    cp $(MAN2) $(MANDIR)/$(MAN2)
  2013. X
  2014. Xinstallexec: all
  2015. X        cp $(TARGET1) $(BINDIR)/$(MTYPE)/$(TARGET1)
  2016. X        cp $(TARGET2) $(BINDIR)/$(MTYPE)/$(TARGET2)
  2017. Xtar:
  2018. X    rm -fr setd.src
  2019. X    mkdir setd.src
  2020. X    cp *.c setd.src
  2021. X    cp *.h setd.src
  2022. X    cp setd.1 setd.src
  2023. X    cp mark.1 setd.src
  2024. X    cp README setd.src
  2025. X    cp Makefile setd.src
  2026. X    tar -cf - setd.src | compress > setd.tar.Z
  2027. X    rm -fr setd.src
  2028. END_OF_FILE
  2029. if test 1440 -ne `wc -c <'Makefile'`; then
  2030.     echo shar: \"'Makefile'\" unpacked with wrong size!
  2031. fi
  2032. # end of 'Makefile'
  2033. fi
  2034. if test -f 'README' -a "${1}" != "-c" ; then 
  2035.   echo shar: Will not clobber existing file \"'README'\"
  2036. else
  2037. echo shar: Extracting \"'README'\" \(1190 characters\)
  2038. sed "s/^X//" >'README' <<'END_OF_FILE'
  2039. XSetd and Mark Utilities
  2040. XSunil William Savkar
  2041. Xsunil@hal.com
  2042. XHaL Computer Systems Inc.
  2043. X
  2044. XSetd and mark are two utilities useful for enhancing the change
  2045. Xdirectory built in.  Setd allow change directories using marks,
  2046. Xenvironment variables, or a built in queue.
  2047. X
  2048. XMark is used to generate the translation list from directory
  2049. Xmarks to full pathnames.
  2050. X
  2051. X1) Please read the man pages which come with the distribution
  2052. X    nroff -t -man setd.1 | more    <== to view
  2053. X    nroff -t -man mark.1 | more
  2054. X    psroff -man setd.1        <== to print
  2055. X    psroff -man mark.1
  2056. X
  2057. X2) Modify Makefile to have OFLAG reflect the type of machine you are
  2058. X   on.  SUN, HP, IBM, etcetera.  These two programs have been run on
  2059. X   Sparcs, HPs, IBM RS/6000s, Solbournes, and Sun 3s.  It doesn't require
  2060. X   anything special installed.  Therefore if you are using a machine other
  2061. X   than these, it will take little or no effort to get this to compile in
  2062. X   any flavour of UNIX.
  2063. X
  2064. X   Also modify places to copy the files, put the man pages, etcetera.
  2065. X
  2066. X3) type    make copy to copy to the /usr/bin area and to the man area.
  2067. X
  2068. X4) Remember to set the environment variables MARK_DIR and SETD_DIR    
  2069. X
  2070. X5) Bugs or enhancements?  Please update me at sunil@hal.com
  2071. X
  2072. X
  2073. END_OF_FILE
  2074. if test 1190 -ne `wc -c <'README'`; then
  2075.     echo shar: \"'README'\" unpacked with wrong size!
  2076. fi
  2077. # end of 'README'
  2078. fi
  2079. if test -f 'DISCLOSURE' -a "${1}" != "-c" ; then 
  2080.   echo shar: Will not clobber existing file \"'DISCLOSURE'\"
  2081. else
  2082. echo shar: Extracting \"'DISCLOSURE'\" \(418 characters\)
  2083. sed "s/^X//" >'DISCLOSURE' <<'END_OF_FILE'
  2084. XSunil William Savkar
  2085. Xsunil@hal.com
  2086. XHaL Computer Systems Inc.
  2087. X
  2088. XThis source may be modified or copied freely.  The intent
  2089. Xis the free distribution of a useful utility used for moving
  2090. Xbetween directories.  Any modifications and additions, along
  2091. Xwith bug reports should be sent to the author, so all might
  2092. Xbenefit!
  2093. X
  2094. XHaL Computer Systems Corporation is in no way held legally or
  2095. Xotherwise liable for the software herein.  
  2096. END_OF_FILE
  2097. if test 418 -ne `wc -c <'DISCLOSURE'`; then
  2098.     echo shar: \"'DISCLOSURE'\" unpacked with wrong size!
  2099. fi
  2100. # end of 'DISCLOSURE'
  2101. fi
  2102. echo shar: End of shell archive.
  2103. exit 0
  2104.